【C++】C++下的简易中国象棋

您所在的位置:网站首页 中国象棋该怎么下 视频 【C++】C++下的简易中国象棋

【C++】C++下的简易中国象棋

2024-07-11 12:26| 来源: 网络整理| 查看: 265

参考自Originum学长的博客,个人进行了一些小修改, 原博客地址:https://blog.csdn.net/Originum/article/details/80356452 联系邮箱:[email protected]

本人博客地址:Megalomania

一个简单的中国象棋游戏,主要实现: 1、两人对弈; 2、简单的棋子移动以及规则判断,不符合规则便重走; 3、有一方获胜便结束游戏。

一、类的设计 “Chess”类: (1) 私有成员有int型的Id,用于记录棋子的归属以及判断轮到的玩家是否可以移动; (2) 公共成员函数有Get函数来获取Id,以及判断走法是否正确的Judgement纯虚函数; (3) 作为基类来派生出其他棋子的类。

具体代码如下:

class Chess { private: int Id; public: Chess(int x) :Id(x) {} int Get() //取ID { return Id; } virtual bool Judgement(Chessboard& ch, int startx, int starty, int endx, int endy) = 0;//判断走步合理性 virtual ~Chess() {} }; “Chessboard”类: (1) 私有成员有一个10*11的指向Chess类的指针(为了方便操作将0的位置腾了出来),用于存放棋子的地址; (2) 还有一个Char型的Chessword数组用于存放棋子的名字(一个汉字占4个Char型空间); (3) 公共成员部分有static int型的 Player用于记录轮到哪个玩家以及哪个玩家获胜。

具体实现代码如下:

class Chessboard { private: Chess *c[10][11]; //棋盘:X为横(9),Y为纵(10),从1开始记 char Chessword[15][4] = { "兵","炮","车","马","相","仕","帅"," ","将","士","象","馬","車","砲","卒" }; public: static int Player; //上半区为1,下半区为-1 static bool End; //判断是否结束 Chessboard(); Chess *Get(int x, int y);//返回指定点的指针 int Getid(int x, int y);//返回指定点处棋子ID的指针 bool Move(int startx, int starty, int endx, int endy); //移动 void Init(); //初始化棋子 void Show(); //打印 void Play(); //开始游戏 ~Chessboard(); }; 二、具体变量的意义

红方棋子:“兵”,“炮”,“车”,“马”,“相”,“仕”,“帅” Id为:7 6 5 4 3 2 1 绿方棋子:“将”,“士”,“象”,“馬”,“車”,“砲”,“卒” Id为:-1 -2 - 3 -4 -5 -6 -7

用于实现移动的变量: startx,starty: 开始的位置; endx,endy:目标的位置; S_Id: 存储开始位置的棋子的编号,若该点没有棋子(空指针),则值为0; E_Id: 存储目标位置的棋子的编号,若该点没有棋子(空指针),则值为0; TempX: 开始位置到目标位置的x坐标的偏移量(startx-endx); TempY: 开始位置到目标位置的y坐标的偏移量(starty-endy)。

三、实现走棋

每次把位置信息传到Chessboard类的Move()函数时,会判断:

传入的两个位置是否越界(超出了10*11数组的范围),越界则返回false。传入的开始位置的点的id是否为零(当点上无棋子,也就是空指针的时候为零),若为零则返回false。当前选的棋子是否是这一回对应那一方的棋子,若不是则返回false。对当前棋子的具体规则进行判断(通过指针调用虚函数,判断该棋子的具体规则)。若错误则返回false。

若以上判断都准确无误,则把棋子走到对应位置:

不吃子:目标位置为空指针时,把目标位置的指针指向该棋子对象,把棋子的起始位置指针赋值NULL,设为空指针。吃子:delete目标位置的棋子对象,该棋子被吃。把目标位置的指针指向该棋子对象,把棋子的起始位置指针赋值NULL,设为空指针。 四、判断结束

判断结束:

棋盘类有一个静态变量bool End, 初始化为true。当将(帅)对象被析构时,把end赋值为false,表示棋局结束,退出走棋的循环(while(chessboard :: end)控制走棋是否继续)。 ~General() { Chessboard::End = false; } 当有一位玩家的某一步棋使双方的将(帅)面对面时,直接判负。具体实现是检测将(帅)所在的4、5、6 三列中将和帅是否在同一类且两者间的指针为全为空指针; int ifalg = 0; for (int i = 4; i < 7; i++) { for (int j = 1; j < 11; j++) { if (c[i][j] != NULL) { if ((int)fabs(c[i][j]->Get()) == 1) { iflag++; } else if (iflag != 0 && iflag != 2) { if ((int)fabs(c[i][j]->Get()) != 1) { iflag--; } } } } } if (iflag == 2) { Player *= -1; Chessboard::End = false; }

输出胜利的一方的信息: 棋盘类有一个静态变量int player,初始化为-1,每走棋一次乘以-1,在1与-1之间交替表示棋手的轮流下棋。以此来鉴别胜利的是哪一方

五、某些棋子的规则算法

判断目标点是否是己方的棋:两方的子的Id互为相反数,所以只有当S_Id* E_Id>0时表示目标位置是己方的子,不能走。因而只有满足S_Id*E_Id= 4 && endx = 1 && endy = 8 && endy



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3